﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Framework.Message.SMS.SGIP.Commands
{
    /// <summary>
    /// 在SP和SMG的通信中，SP用Submit命令向SMG提交MT短消息，发送到用户的手机中。SMG接收到Submit命令，会返回Submit_Resp应答。SMG根据Submit命令中的付费号码，判断出该命令是否应从本地SMSC发送，如果属于本地发送，则直接发送到相应的SMSC，否则路由至相应的SMG。
    /// 在SMG和SMG的通信中，Submit命令用于SMG客户端向服务器端路由从SP收到的MT短消息。服务器端接收到Submit命令后，再发送到与之相连的目的SMSC。
    /// </summary>
    public class SubmitCommand : Command
    {
        #region 变量与属性
        private string _SPNumber = "";
        /// <summary>
        /// SP的接入号码
        /// </summary>
        public string SPNumber
        {
            get { return _SPNumber; }
            set { _SPNumber = value; }
        }

        private string _ChargeNumber = "";
        /// <summary>
        /// 付费号码，手机号码前加“86”国别标志；当且仅当群发且对用户收费时为空；如果为空，则该条短消息产生的费用由UserNumber代表的用户支付；如果为全零字符串“000000000000000000000”，表示该条短消息产生的费用由SP支付。
        /// </summary>
        public string ChargeNumber
        {
            get { return _ChargeNumber; }
            set { _ChargeNumber = value; }
        }

        private List<string> _UserNumber;
        /// <summary>
        /// 接收该短消息的手机号，该字段重复UserCount指定的次数，手机号码前加“86”国别标志
        /// 接收短消息的手机数量，取值范围1至100
        /// </summary>
        public List<string> UserNumber
        {
            get
            {
                if (_UserNumber == null)
                {
                    _UserNumber = new List<string>();
                }
                return _UserNumber;
            }
            set { _UserNumber = value; }
        }

        private string _CorpId = "";
        /// <summary>
        /// 企业代码，取值范围0-99999
        /// </summary>
        public string CorpId
        {
            get { return _CorpId; }
            set { _CorpId = value; }
        }

        private string _ServiceType = "";
        /// <summary>
        /// 业务代码，由SP定义
        /// </summary>
        public string ServiceType
        {
            get { return _ServiceType; }
            set { _ServiceType = value; }
        }

        private FeeType _FeeType;
        /// <summary>
        /// 计费类型
        /// </summary>
        public FeeType FeeType
        {
            get { return _FeeType; }
            set { _FeeType = value; }
        }

        private string _FeeValue = "0";
        /// <summary>
        /// 取值范围0-99999，该条短消息的收费值，单位为分，由SP定义
        /// 对于包月制收费的用户，该值为月租费的值
        /// </summary>
        public string FeeValue
        {
            get { return _FeeValue; }
            set { _FeeValue = value; }
        }

        private string _GivenValue = "0";
        /// <summary>
        /// 取值范围0-99999，赠送用户的话费，单位为分，由SP定义，特指由SP向用户发送广告时的赠送话费
        /// </summary>
        public string GivenValue
        {
            get { return _GivenValue; }
            set { _GivenValue = value; }
        }

        private SubmitAgentFlag _AgentFlag;
        /// <summary>
        /// 代收费标志，0：应收；1：实收
        /// </summary>
        public SubmitAgentFlag AgentFlag
        {
            get { return _AgentFlag; }
            set { _AgentFlag = value; }
        }

        private SubmitMorelatetoMTFlag _MorelatetoMTFlag;
        /// <summary>
        /// 引起MT消息的原因
        /// </summary>
        public SubmitMorelatetoMTFlag MorelatetoMTFlag
        {
            get { return _MorelatetoMTFlag; }
            set { _MorelatetoMTFlag = value; }
        }

        private int _Priority = 0;
        /// <summary>
        /// 优先级0-9从低到高，默认为0
        /// </summary>
        public int Priority
        {
            get { return _Priority; }
            set { _Priority = value; }
        }

        private string _ExpireTime = "032+";
        /// <summary>
        /// 短消息寿命的终止时间，如果为空，表示使用短消息中心的缺省值。时间内容为16个字符，格式为”yymmddhhmmsstnnp” ，其中“tnnp”取固定值“032+”，即默认系统为北京时间
        /// </summary>
        public string ExpireTime
        {
            get { return _ExpireTime; }
            set { _ExpireTime = value; }
        }

        private string _ScheduleTime = "032+";
        /// <summary>
        /// 短消息定时发送的时间，如果为空，表示立刻发送该短消息。时间内容为16个字符，格式为“yymmddhhmmsstnnp” ，其中“tnnp”取固定值“032+”，即默认系统为北京时间
        /// </summary>
        public string ScheduleTime
        {
            get { return _ScheduleTime; }
            set { _ScheduleTime = value; }
        }

        private SubmitReportFlag _ReportFlag = SubmitReportFlag.ErrorReport;
        /// <summary>
        /// 状态报告标记
        /// </summary>
        public SubmitReportFlag ReportFlag
        {
            get { return _ReportFlag; }
            set { _ReportFlag = value; }
        }

        private int _TP_pid = 0;
        /// <summary>
        /// GSM协议类型。详细解释请参考GSM03.40中的9.2.3.9
        /// </summary>
        public int TP_pid
        {
            get { return _TP_pid; }
            set { _TP_pid = value; }
        }

        private int _TP_udhi = 0;
        /// <summary>
        /// GSM协议类型。详细解释请参考GSM03.40中的9.2.3.23,仅使用1位，右对齐
        /// </summary>
        public int TP_udhi
        {
            get { return _TP_udhi; }
            set { _TP_udhi = value; }
        }

        private MessageCoding _MessageCoding;
        /// <summary>
        /// 短消息的编码格式。
        /// </summary>
        public MessageCoding MessageCoding
        {
            get { return _MessageCoding; }
            set { _MessageCoding = value; }
        }

        private SubmitMessageType _MessageType;
        /// <summary>
        /// 信息类型
        /// </summary>
        public SubmitMessageType MessageType
        {
            get { return _MessageType; }
            set { _MessageType = value; }
        }

        private uint _MessageLength = 0;
        /// <summary>
        /// 短消息的长度
        /// </summary>
        public uint MessageLength
        {
            get { return _MessageLength; }
            set
            {
                if (_MessageLength != value)
                {
                    _MessageLength = value;
                    Header.MessageLength = CommandHeader.HeaderLength + this.BodyLength;
                }
            }
        }

        private string _MessageContent = "";
        /// <summary>
        /// 短消息的内容
        /// </summary>
        public string MessageContent
        {
            get { return _MessageContent; }
            set
            {
                if (_MessageContent != value)
                {
                    _MessageContent = value;
                    this.MessageLength = (uint)ByteStringConvert.GetString2ByteCount(_MessageContent, _MessageCoding);
                }
            }
        }

        private string _Reserve = "";
        /// <summary>
        /// 保留，扩展用
        /// </summary>
        public string Reserve
        {
            get { return _Reserve; }
            set { _Reserve = value; }
        }
        #endregion

        public override uint BodyLength
        {
            get { return (uint)(21 + 21 + 1 + (21 * this.UserNumber.Count) + 5 + 10 + 1 + 6 + 6 + 1 + 1 + 1 + 16 + 16 + 1 + 1 + 1 + 1 + 1 + 4 + this.MessageLength + 8); }
        }

        public override SGIPCommandType CommandType
        {
            get { return SGIPCommandType.Submit; }
        }

        #region 构造函数
        public SubmitCommand()
        {
        }

        public SubmitCommand(byte[] bytes)
            : base(bytes)
        {
        }

        public SubmitCommand(byte[] bytes, int startIndex)
            : base(bytes, startIndex)
        {
        }

        public SubmitCommand(CommandSequence sequence)
            : base(sequence)
        {
        } 
        #endregion

        protected override void BytesTo(byte[] bytes, int startIndex)
        {
            int i = (int)CommandHeader.HeaderLength;
            base.BytesTo(bytes, startIndex);
            _SPNumber = ByteStringConvert.Bytes2String(bytes, i, 21, MessageCoding.ASCII).TrimEnd('\0');
            i += 21;
            _ChargeNumber = ByteStringConvert.Bytes2String(bytes, i, 21, MessageCoding.ASCII).TrimEnd('\0');
            i += 21;
            int userCount = (int)bytes[i];
            i++;
            for (int j = 0; j < userCount; j++)
            {
                this._UserNumber.Add(ByteStringConvert.Bytes2String(bytes, i, 21, MessageCoding.ASCII).TrimEnd('\0'));
                i += 21;
            }
            _CorpId = ByteStringConvert.Bytes2String(bytes, i, 5, MessageCoding.ASCII).TrimEnd('\0');
            i += 5;
            _ServiceType = ByteStringConvert.Bytes2String(bytes, i, 10, MessageCoding.ASCII).TrimEnd('\0');
            i += 10;
            _FeeType = (SGIP.FeeType)bytes[i];
            i++;
            _FeeValue = ByteStringConvert.Bytes2String(bytes, i, 6, MessageCoding.ASCII).TrimEnd('\0');
            i += 6;
            _GivenValue = ByteStringConvert.Bytes2String(bytes, i, 6, MessageCoding.ASCII).TrimEnd('\0');
            i += 6;
            _AgentFlag = (SubmitAgentFlag)bytes[i];
            i++;
            _MorelatetoMTFlag = (SubmitMorelatetoMTFlag)bytes[i];
            i++;
            _Priority = (int)bytes[i];
            i++;
            _ExpireTime = ByteStringConvert.Bytes2String(bytes, i, 16, MessageCoding.ASCII).TrimEnd('\0');
            i += 16;
            _ScheduleTime = ByteStringConvert.Bytes2String(bytes, i, 16, MessageCoding.ASCII).TrimEnd('\0');
            i += 16;
            _ReportFlag = (SubmitReportFlag)bytes[i];
            i++;
            _TP_pid = (int)bytes[i];
            i++;
            _TP_udhi = (int)bytes[i];
            i++;
            _MessageCoding = (MessageCoding)bytes[i];
            i++;
            _MessageType = (SubmitMessageType)bytes[i];
            i++;
            _MessageLength = ByteIntConvert.Bytes2UInt(bytes, i);
            i += 4;
            _MessageContent = ByteStringConvert.Bytes2String(bytes, i, (int)_MessageLength, this._MessageCoding).TrimEnd('\0');
            i += (int)_MessageLength;
            _Reserve = ByteStringConvert.Bytes2String(bytes, i, 8, MessageCoding.ASCII).TrimEnd('\0');
        }

        public override byte[] ToBytes()
        {
            int i = (int)CommandHeader.HeaderLength;
            byte[] bytes = base.ToBytes();
            ByteStringConvert.String2Bytes(this._SPNumber.PadRight(21, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
            i += 21;
            ByteStringConvert.String2Bytes(this._ChargeNumber.PadRight(21, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
            i += 21;
            bytes[i] = (byte)this.UserNumber.Count;
            i++;
            foreach (string item in this.UserNumber)
            {
                ByteStringConvert.String2Bytes(item.PadRight(21, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
                i += 21;
            }
            ByteStringConvert.String2Bytes(this._CorpId.PadRight(5, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
            i += 5;
            ByteStringConvert.String2Bytes(this._ServiceType.PadRight(10, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
            i += 10;
            bytes[i] = (byte)this._FeeType;
            i++;
            ByteStringConvert.String2Bytes(this._FeeValue.PadRight(6, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
            i += 6;
            ByteStringConvert.String2Bytes(this._GivenValue.PadRight(6, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
            i += 6;
            bytes[i] = (byte)this._AgentFlag;
            i++;
            bytes[i] = (byte)this._MorelatetoMTFlag;
            i++;
            bytes[i] = (byte)this._Priority;
            i++;
            ByteStringConvert.String2Bytes(this._ExpireTime.PadRight(16, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
            i += 16;
            ByteStringConvert.String2Bytes(this._ScheduleTime.PadRight(16, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
            i += 16;
            bytes[i] = (byte)this._ReportFlag;
            i++;
            bytes[i] = (byte)this._TP_pid;
            i++;
            bytes[i] = (byte)this._TP_udhi;
            i++;
            bytes[i] = (byte)this._MessageCoding;
            i++;
            bytes[i] = (byte)this._MessageType;
            i++;
            ByteIntConvert.UInt2Bytes(this.MessageLength).CopyTo(bytes, i);
            i += 4;
            ByteStringConvert.String2Bytes(this._MessageContent, this._MessageCoding).CopyTo(bytes, i);
            i += (int)_MessageLength;
            ByteStringConvert.String2Bytes(this._Reserve.PadRight(8, '\0'), MessageCoding.ASCII).CopyTo(bytes, i);
            return bytes;
        }
    }
}
